home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / preproc.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  76KB  |  2,507 lines

  1. /* TODO:
  2.  
  3.    ---- HIGHEST PRIORITY ----
  4.  
  5.    * #ifndef
  6.  
  7.    * #if/#elif - Bearbeitung
  8.  
  9.    * leere argument-/tokenlists erlauben
  10.  
  11.    * Anzahl der Argumente checken (auch zuviele ergeben einen Error)
  12.  
  13.    * bei REDEFINING und allowredefinition=0 tokenlist genau ueberpruefen
  14.  
  15.    * Aufteilen in mehrere Sourcen main.c pplists.c etc.
  16.    * Einige Variablen umbenennen (x,y,i,j,l,n etc =8)
  17.  
  18.    -----------------------------------------------------------------
  19.  
  20.    * Verbesserungen:
  21.    * - Nach malloc()/vor free() ueberpruefen ob NULL-Pointer
  22.    * - Statt per dlen per Ptr2EOL abfragen..
  23.  
  24.    * Fragen an Volker:
  25.    * - _ alleine ein Identifier ? Ja
  26.  
  27.    ---- LOWEST PRIORITY ----
  28.  
  29.    * - Token loeschen, wenn nur noch TokenList benutzt wird.
  30.  
  31.    * - ParseIdent.. optimieren
  32.  
  33.    * - Rest optimieren =8)
  34.  
  35.    * - PreParsing umschreiben.. __LINE__ muss mit der echten
  36.    *    Zeilennummer uebereinstimmen (die LFs drinlassen)
  37.  */
  38.  
  39. /*
  40.  * PreProcessor
  41.  * $VER: VBPP V0.00 (19 Sep 1995)
  42.  * (w) 1995 by Thorsten Schaaps
  43.  */
  44.  
  45. #include <time.h>
  46.  
  47. #include "vbc.h"
  48. #include "vbpp.h"
  49.  
  50. /*vb:   */
  51. static char FILE_[]=__FILE__;
  52.  
  53. /*vb:   */
  54. char pp_version[] = "vbpp V0.00 (w) 1995 by Thorsten Schaaps";
  55.  
  56.                                 /* #define MAXIFNESTING 1024 *//*vb: ifnesting==incnesting */
  57.  
  58. FILE *in[MAXINCNESTING];        /*  Sourcefiles     */
  59. int zn[MAXINCNESTING];          /*  Zeilennummern   */
  60. char *filename[MAXINCNESTING];  /*  Filenamen   */
  61. int incnesting;                 /*  aktuelle Verschachtelungstiefe  */
  62. unsigned long linenr;           /*  Zeilennummer */
  63.  
  64. char *incpath[MAXINCPATHS] =
  65. {"vinclude:"};                  /*  Includepfade    */
  66.  
  67. int incpathc = 1;               /*  Anzahl der Includepfade     */
  68.  
  69. char ppstring[MAXPPINPUT];
  70.  
  71. int cmtnesting = 0;             /*  aktuelle Kommentar-Versch.-Tiefe */
  72.  
  73.                                           /*int ifnesting; *//*vb: *//*  aktuelle IF-Tiefe */
  74. /*vb: ifnesting==incnesting */
  75. short ifstatus[MAXINCNESTING];  /* Array fuer Status-Verschachtelung */
  76. int if_cnt;                     /* Zaehler fuer #if's waehrend do_output=0 */
  77. int abs_if_cnt;                 /* zaehlt auch waehrend do_output */
  78.  
  79. int do_output = 1;              /* Flag zur Erzeugung eines Outputs */
  80.  
  81. struct strnode *strlist;
  82.  
  83. struct mnode *mlist;
  84.  
  85. int did_expand;
  86.  
  87. /* Temporaere Debugging-Routinen */
  88. void PrintSN(struct strnode *tl)
  89. {
  90.     switch (tl->type) {
  91.     case NORMAL:
  92.         printf(" Normal........:");
  93.         break;
  94.     case PP_IDENT:
  95.         printf(" Identifier....:");
  96.         break;
  97.     case ARGUMENT:
  98.         printf(" Argument Nr.%2d:", tl->number);
  99.         break;
  100.     case NUMBER:
  101.         printf(" Number........:");
  102.         break;
  103.     case PP_STR:
  104.         printf(" String........:");
  105.         break;
  106.     case SPACE:
  107.         printf(" Space.........:");
  108.         break;
  109.     case SPECIAL:
  110.         printf(" Special..Nr.%2d:", tl->flags);
  111.         break;
  112.     default:
  113.         printf(" unknown..Nr.%2d:", tl->type);
  114.         break;
  115.     }
  116.     printf(" %s\n", tl->str);
  117. }
  118. void PrintTL(struct strnode *tl)
  119. {
  120.  
  121. #ifdef bla
  122.  
  123.     if (tl) {
  124.         printf("TokenList:\n");
  125.         while (tl) {
  126.             PrintSN(tl);
  127.             tl = tl->next;
  128.         }
  129.     }
  130. #endif
  131.  
  132. }
  133.  
  134.  
  135. /* ******* Listen-Funktionen ******* */
  136.  
  137. /* AddMakroNode - Fuegt eine Node an den Anfang einer Liste ein */
  138. void AddMakroNode(struct mnode **list, struct mnode *node)
  139. {
  140.  
  141.     if (DEBUG & 32)
  142.         puts("AddMakroNode");
  143.  
  144.     if (node) {
  145.         node->prev = NULL;
  146.         node->next = *list;
  147.         *list = node;
  148.         if (node->next)
  149.             node->next->prev = node;
  150.     }
  151. }
  152.  
  153.  
  154. /* AddStrNode - Fuegt eine Node in die Liste ein */
  155. void AddStrNode(struct strnode **list, struct strnode *node, char *str)
  156. {
  157.  
  158.     if (DEBUG & 32)
  159.         puts("AddStrNode");
  160.  
  161.  
  162.     if (node || str) {
  163.         if (!node)
  164.             node = (struct strnode *) malloc(sizeof(struct strnode));
  165.         /* HIER: Rueckgabewert wegen Fehler ! */
  166.         if (!node) {
  167.             error(196);
  168.         } else {
  169.             node->prev = NULL;
  170.             node->next = *list;
  171.             if (str)
  172.                 node->str = str;
  173.             *list = node;
  174.             if (node->next)
  175.                 node->next->prev = node;
  176.         }
  177.     }
  178. }
  179.  
  180.  
  181. /* AddStrNodeBehind - Fuegt eine Node ans Ende der Liste ein */
  182. void AddStrNodeBehind(struct strnode **list, struct strnode *node, char *str)
  183. {
  184.     struct strnode *listnode;
  185.  
  186.     if (DEBUG & 32)
  187.         puts("AddStrNodeBehind");
  188.  
  189.  
  190.     if (node || str) {
  191.         if (!node)
  192.             node = (struct strnode *) malloc(sizeof(struct strnode));
  193.         if (!node) {
  194.             error(196);
  195.         } else {
  196.             if (!*list) {
  197.                 node->prev = NULL;
  198.                 node->next = NULL;
  199.                 *list = node;
  200.             } else {
  201.                 listnode = *list;
  202.                 while (listnode->next) {
  203.                     listnode = listnode->next;
  204.                 }
  205.                 node->prev = listnode;
  206.                 node->next = NULL;
  207.                 listnode->next = node;
  208.             }
  209.             if (str)
  210.                 node->str = str;
  211.         }
  212.     }
  213. }
  214.  
  215.  
  216. /* RemMakroNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */
  217. void RemMakroNode(struct mnode **list, struct mnode *node)
  218. {
  219.  
  220.     if (DEBUG & 32)
  221.         puts("RemMakroNode");
  222.  
  223.  
  224.     if (node->prev) {
  225.         if (node->next)
  226.             node->next->prev = node->prev;
  227.         node->prev->next = node->next;
  228.     } else {
  229.         if (node->next)
  230.             node->next->prev = NULL;
  231.         *list = node->next;
  232.     }
  233.     node->next = node->prev = NULL;
  234. }
  235.  
  236. /* InsertMakroNode - Setzt eine Node hinter einer anderen ein */
  237. void InsertMakroNode(struct mnode **list, struct mnode *node, struct mnode *behind)
  238. {
  239.  
  240.     if (DEBUG & 32)
  241.         puts("InsertMakroNode");
  242.  
  243.  
  244.     if (behind) {
  245.         node->prev = behind;
  246.         node->next = behind->next;
  247.         behind->next = node;
  248.         if (node->next)
  249.             node->next->prev = node;
  250.     } else
  251.         AddMakroNode(list, node);
  252. }
  253.  
  254. /* RemStrNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */
  255. void RemStrNode(struct strnode **list, struct strnode *node)
  256. {
  257.  
  258.     if (DEBUG & 32)
  259.         puts("RemStrNode");
  260.  
  261.  
  262.     if (node->prev) {
  263.         if (node->next)
  264.             node->next->prev = node->prev;
  265.         node->prev->next = node->next;
  266.     } else {
  267.         if (node->next)
  268.             node->next->prev = NULL;
  269.         *list = node->next;
  270.     }
  271.     node->next = node->prev = NULL;
  272. }
  273.  
  274.  
  275. /* FindMakroNode - sucht den passenden Eintrag in der Liste
  276.  *                 len=0 - der gesamte String muss uebereinstimmen
  277.  *                 len>0 - die ersten len Zeichen muessen stimmen
  278.  */
  279. struct mnode *FindMakroNode(struct mnode *list, char *str, int len)
  280. {
  281.  
  282.     if (DEBUG & 32)
  283.         puts("FindMakroNode");
  284.  
  285.     while (list) {
  286.         if (len) {
  287.             if ((strlen(list->name) == len) && (!strncmp(list->name, str, len)))
  288.                 return (list);
  289.         } else {
  290.             if (!strcmp(list->name, str))
  291.                 return (list);
  292.         }
  293.         list = list->next;
  294.     }
  295.     return (0);
  296. }
  297.  
  298.  
  299. /* DelMakroNode - gibt den gesamten Speicher einer Node frei, ist list#NULL
  300.  *                wird die Node vorher aus der Liste entfernt
  301.  */
  302. void DelMakroNode(struct mnode **list, struct mnode *node)
  303. {
  304.  
  305.     if (DEBUG & 32)
  306.         puts("DelMakroNode");
  307.  
  308.  
  309.     if (node) {
  310.         if (list && *list)
  311.             RemMakroNode(list, node);
  312.         if (node->name)
  313.             free(node->name);
  314.         if (node->args)
  315.             free(node->args);
  316.         if (node->token)
  317.             free(node->token);
  318.         if (node->tokenlist)
  319.             DelStrList(&node->tokenlist);
  320.         free(node);
  321.     }
  322. }
  323.  
  324.  
  325. /* DelStrNode - gibt den gesamten Speicher einer Node frei, ist list#NULL
  326.  *              wird die Node vorher aus der Liste entfernt
  327.  */
  328. void DelStrNode(struct strnode **list, struct strnode *node)
  329. {
  330.  
  331.     if (DEBUG & 32)
  332.         puts("DelStrNode");
  333.  
  334.  
  335.     if (node) {
  336.         if (list && *list)
  337.             RemStrNode(list, node);
  338.         if (node->str)
  339.             free(node->str);
  340.         free(node);
  341.     }
  342. }
  343.  
  344. void MergeStrNodes(struct strnode *prev, struct strnode *next)
  345. {
  346.     /* next will now be deleted and prev->str will be */
  347.     /* the joined strings from prev&next */
  348.     char *newstr;
  349. /*vb:   */
  350.     char c, *s, *d;
  351.  
  352.     if (DEBUG & 32)
  353.         puts("MergeStrNodes");
  354.  
  355.  
  356.     newstr = (char *) malloc(prev->len + next->len + 1);
  357. /*vb: string-Routinen ersetzt (hoffentlich schneller)
  358.    strcpy(newstr,prev->str);
  359.    strcat(newstr,next->str);
  360.  */
  361.     d = newstr;
  362.     s = prev->str;
  363.     do {
  364.         c = *s++;
  365.         *d++ = c;
  366.     } while (c);
  367.     d--;
  368.     s = next->str;
  369.     do {
  370.         c = *s++;
  371.         *d++ = c;
  372.     } while (c);
  373.  
  374.     if (prev->str)
  375.         free(prev->str);        /*vb: wenn prev->str==0 knallts doch schon oben? */
  376.     prev->str = newstr;
  377.     prev->len += next->len;
  378.     DelStrNode(NULL, next);
  379. }
  380.  
  381. /* DelMakroList - loescht eine gesamte Liste */
  382. void DelMakroList(struct mnode **list)
  383. {
  384.  
  385.     if (DEBUG & 32)
  386.         puts("DelMakroList");
  387.  
  388.  
  389.     while (*list)
  390.         DelMakroNode(list, *list);
  391.     /*  *list=NULL; *//*vb: *list==0 */
  392. }
  393.  
  394.  
  395. /* DelStrList - loescht eine gesamte Liste samt der Nodes/Strings */
  396. void DelStrList(struct strnode **list)
  397. {
  398.  
  399.     if (DEBUG & 32)
  400.         puts("DelStrList");
  401.  
  402.  
  403.     while (*list)
  404.         DelStrNode(list, *list);
  405.     /*  *list=NULL; *//*vb: *list==0 */
  406. }
  407.  
  408. /* AllocSpace - erzeugt eine StrNode vom Typ Space */
  409. struct strnode *AllocSpace()
  410. {
  411.     struct strnode *newnode;
  412.     char *newstr;
  413.  
  414.  
  415.     if (DEBUG & 32)
  416.         puts("AllocSpace");
  417.  
  418.  
  419.     newstr = (char *) malloc(2);
  420.     if (newstr) {
  421.         newstr[0] = ' ';
  422.         newstr[1] = 0;
  423.         newnode = (struct strnode *) malloc(sizeof(struct strnode));
  424.         if (newnode) {
  425.             newnode->str = newstr;
  426.             newnode->type = SPACE;
  427.             newnode->len = 1;
  428.             newnode->next = newnode->prev = NULL;
  429.             newnode->flags = newnode->number = 0;
  430.             return (newnode);
  431.         }
  432.     }
  433.     return (NULL);
  434. }
  435.  
  436.  
  437. /* CloneStrList - erstellt eine exakte Kopie der Liste oder eines Ausschnittes */
  438. /*                wenn listend#NULL */
  439. struct strnode *CloneStrList(struct strnode *list, struct strnode *listend)
  440. {
  441.     struct strnode *prevnode = NULL, *newnode, *newlist = NULL;
  442.     char *newstr;
  443.  
  444.     if (DEBUG & 32)
  445.         puts("CloneStrList");
  446.  
  447.  
  448.     while (list) {
  449.         newnode = (struct strnode *) malloc(sizeof(struct strnode));
  450.         if (!newnode) {
  451.             DelStrList(&newlist);
  452.             return (NULL);
  453.         }
  454.         newstr = (char *) malloc(list->len + 1);
  455.         if (!newstr) {
  456.             free(newnode);
  457.             DelStrList(&newlist);
  458.             return (NULL);
  459.         }
  460.         strcpy(newstr, list->str);
  461.         newnode->str = newstr;
  462.         newnode->len = list->len;
  463.         newnode->flags = list->flags;
  464.         newnode->type = list->type;
  465.         newnode->number = list->number;
  466.         newnode->next = NULL;
  467.         newnode->prev = prevnode;
  468.  
  469.         if (prevnode)
  470.             prevnode->next = newnode;
  471.         else
  472.             newlist = newnode;
  473.         prevnode = newnode;
  474.  
  475.         if (listend && list == listend)
  476.             list = NULL;
  477.         else
  478.             list = list->next;
  479.     }
  480.     return (newlist);
  481. }
  482.  
  483.  
  484. /* DoMakroFunction - erstellt eine StrList entsprechend des Function-Makros */
  485. struct strnode *DoMakroFunction(struct mnode *makro)
  486. {
  487.     struct strnode *result = NULL;
  488.     char *newstr = NULL, *timestr = NULL;
  489.     int len, type;
  490.     time_t timevalue;
  491.  
  492.     if (DEBUG & 32)
  493.         puts("DoMakroFunction");
  494.  
  495.  
  496.     if (makro->flags & FUNCTION) {
  497.         switch (makro->funcnum) {
  498.         case FUNCLINE:
  499.             newstr = (char *) malloc(11);
  500.             if (!newstr)
  501.                 return (NULL);
  502.             sprintf(newstr, "%lu", linenr);
  503.             len = strlen(newstr);
  504.             type = NUMBER;
  505.             break;
  506.         case FUNCFILE:
  507.             len = strlen(filename[incnesting]);
  508.             newstr = (char *) malloc(len + 1 + 2);
  509.             if (!newstr)
  510.                 return (NULL);
  511.             *newstr = '\"';
  512.             strcpy((newstr + 1), filename[incnesting]);
  513.             strcat(newstr, "\"");
  514.             type = PP_STR;
  515.             break;
  516.         case FUNCDATE:
  517.             type = PP_STR;
  518.             newstr = (char *) malloc(14);
  519.             if (!newstr)
  520.                 return (NULL);
  521.             timevalue = time(0);
  522.             timestr = ctime(&timevalue);
  523.             newstr[0] = '\"';
  524.             strncpy(newstr + 1, timestr + 4, 7);        /* copy 'Mmm dd ' */
  525.             strcpy(newstr + 8, timestr + 20);   /* copy 'yyyy' */
  526.             newstr[12] = '\"';
  527.             newstr[13] = 0;
  528.             len = 13;
  529.             break;
  530.         case FUNCTIME:
  531.             type = PP_STR;
  532.             newstr = (char *) malloc(11);
  533.             if (!newstr)
  534.                 return (NULL);
  535.             timevalue = time(0);
  536.             timestr = ctime(&timevalue);
  537.             newstr[0] = '\"';
  538.             strncpy(newstr + 1, timestr + 11, 8);       /* copy 'hh:mm:ss' */
  539.             newstr[9] = '\"';
  540.             newstr[10] = 0;
  541.             len = 10;
  542.             break;
  543.         default:
  544.             return (NULL);
  545.             break;
  546.         }
  547.         result = (struct strnode *) malloc(sizeof(struct strnode));
  548.         if (!result) {
  549.             if (newstr)
  550.                 free(newstr);
  551.             return (NULL);
  552.         }
  553.         result->prev = result->next = NULL;
  554.         result->str = newstr;
  555.         result->len = len;
  556.         result->number = result->flags = 0;
  557.         result->type = type;
  558.     }
  559.     return (result);
  560. }
  561.  
  562.  
  563. /* *******  String-Funktionen ****** */
  564.  
  565. /* Str2List - parsed einen String in eine StrList */
  566. struct strnode *Str2List(char *str)
  567. {
  568.     struct strnode *newlist = NULL, *newnode = NULL;
  569.     char *temp, *string;
  570.     int length, type, flags;
  571.  
  572.     if (DEBUG & 32)
  573.         puts("Str2List");
  574.  
  575.     while (*str) {
  576.         flags = 0;
  577. /*vb: casts eingefuegt   */
  578.         if (isspace((unsigned char) *str)) {    /* Spaces parsen */
  579.             temp = str + 1;
  580.             length = 1;
  581.             while (*temp && isspace((unsigned char) *temp)) {
  582.                 temp++;
  583.                 length++;
  584.             }
  585.             type = SPACE;
  586.         } else if (*str == '\"') {      /* String parsen */
  587.             temp = str + 1;
  588.             length = 2;
  589.             while (*temp && *temp != '\"')
  590.                 if (*temp == '\\') {
  591.                     temp += 2;
  592.                     length += 2;
  593.                 } else {
  594.                     temp++;
  595.                     length++;
  596.                 }
  597.             type = PP_STR;
  598.         } else if (*str == '\'') {      /* String parsen */
  599.             temp = str + 1;
  600.             length = 2;
  601.             while (*temp && *temp != '\'')
  602.                 if (*temp == '\\') {
  603.                     temp += 2;
  604.                     length += 2;
  605.                 } else {
  606.                     temp++;
  607.                     length++;
  608.                 }
  609.             type = PP_STR;
  610.         } else if (isdigit((unsigned char) *str) || (*str == '.' && isdigit((unsigned char) *(str + 1)))) {
  611.             /* Zahlen parsen */
  612.             temp = str;
  613.             length = 0;
  614.             while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  615.                 temp++;
  616.                 length++;
  617.             }
  618.             if (*temp == '.') {
  619.                 temp++;
  620.                 length++;
  621.                 if (isdigit((unsigned char) *temp) || *temp == 'e' || *temp == 'E')
  622.                     while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  623.                         temp++;
  624.                         length++;
  625.                     }
  626.             }
  627.             if (*(temp - 1) == 'e' || *(temp - 1) == 'E')
  628.                 if (isdigit((unsigned char) *temp) || *temp == '+' || *temp == '-') {
  629.                     temp++;
  630.                     length++;
  631.                     while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  632.                         temp++;
  633.                         length++;
  634.                     }
  635.                 }
  636.             type = NUMBER;
  637.         } else if (isalpha((unsigned char) *str) || *str == '_') {      /* moegl. Identifier parsen */
  638.             temp = str + 1;
  639.             length = 1;
  640.             while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  641.                 temp++;
  642.                 length++;
  643.             }
  644.             type = PP_IDENT;
  645.         } else if (*str) {      /* alles andere als einzelne Zeichen */
  646.             length = 1;
  647.             type = NORMAL;
  648.         }
  649.         string = (char *) malloc(length + 1);
  650.         if (!string) {
  651.             error(196);
  652.             DelStrList(&newlist);
  653.             return (NULL);
  654.         }
  655.         strncpy(string, str, length);
  656.         string[length] = 0;
  657.         str += length;
  658.  
  659.         newnode = (struct strnode *) malloc(sizeof(struct strnode));
  660.         if (!newnode) {
  661.             error(196);
  662.             if (string)
  663.                 free(string);
  664.             return (NULL);
  665.         }
  666.         newnode->str = string;
  667.         newnode->len = length;
  668.         newnode->flags = flags;
  669.         newnode->type = type;
  670.  
  671.         AddStrNodeBehind(&newlist, newnode, NULL);
  672.     }
  673.     return (newlist);
  674. }
  675.  
  676. /* List2Str - schreibt eine Liste als String zurueck */
  677. int List2Str(struct strnode *list, char *str, int maxchars)
  678. {
  679.     int len = 0;
  680.     char c, *p;
  681.  
  682.     if (DEBUG & 32)
  683.         puts("List2Str");
  684.  
  685.  
  686.     *str = 0;
  687.     if (list) {
  688.         while (list) {
  689.             if ((len + (list->len)) > (maxchars - 1)) {
  690.                 error(177);
  691.                 return (0);
  692.             } else {
  693.                 /*vb:   */
  694.                 p = list->str;
  695.                 do {
  696.                     c = *p++;
  697.                     *str++ = c;
  698.                 } while (c);
  699.                 str--;
  700. /*        strcat(str,list->str); */
  701.                 len += list->len;
  702.             }
  703.             list = list->next;
  704.         }
  705.         return (len + 1);
  706.     } else {
  707.         *str = 0;
  708.         return (1);
  709.     }
  710. }
  711.  
  712. /* ListLen - ermittelt die Laenge einer Str-Liste (in Zeichen) */
  713. int ListLen(struct strnode *list)
  714. {
  715.     int len = 0;
  716.     while (list) {
  717.         len += list->len;
  718.         list = list->next;
  719.     }
  720.     return (len);
  721. }
  722.  
  723. /* ListStrLen - ermittelt die Laenge einer Str-List als String   */
  724. /*              d.h. mit " am Anfang und Ende, sowie einem \ vor */
  725. /*              jedem \ und "                                    */
  726. int ListStrLen(struct strnode *list)
  727. {
  728.     int len = 2;
  729.     while (list) {
  730.         if (list->type == SPACE)
  731.             len++;
  732.         else {
  733.             len += list->len;
  734.             if (list->type == PP_STR && list->str[0] == '\"')
  735.                 len += 2;
  736.             else if (list->type == NORMAL && list->str[0] == '\\')
  737.                 len++;
  738.         }
  739.         list = list->next;
  740.     }
  741.     return (len);
  742. }
  743.  
  744. /* CopyList2StrStr - kopiert eine Str-List als String um         */
  745. /*              d.h. mit " am Anfang und Ende, sowie einem \ vor */
  746. /*              jedem \ und "                                    */
  747. CopyList2StrStr(struct strnode * list, char *str)
  748. {
  749.     int len;
  750.  
  751.     if (DEBUG & 32)
  752.         puts("CopyList2StrStr");
  753.  
  754.  
  755.     str[0] = 0;
  756.     if (list) {
  757.         strcpy(str, "\"");
  758.         len = 1;
  759.         while (list) {
  760.             if (list->type == SPACE) {
  761.                 len++;
  762.                 strcat(str, " ");
  763.             } else {
  764.                 len += list->len;
  765.                 if (list->type == PP_STR && list->str[0] == '\"') {
  766.                     strcat(str, "\\");
  767.                     strncat(str, list->str, list->len - 1);
  768.                     strcat(str, "\\\"");
  769.                 } else if (list->type == NORMAL && list->str[0] == '\\') {
  770.                     strcat(str, "\\");
  771.                     strcat(str, list->str);
  772.                 } else
  773.                     strcat(str, list->str);
  774.             }
  775.             list = list->next;
  776.         }
  777.         strcat(str, "\"");
  778.         len++;
  779.     }
  780.     return (len);
  781. }
  782.  
  783. /* NextToSpecial - checked, ob die StrNode neben einem # oder ## steht */
  784. int NextToSpecial(struct strnode *node)
  785. {
  786.     struct strnode *search;
  787.  
  788.     if (DEBUG & 32)
  789.         puts("NextToSpecial");
  790.  
  791.  
  792.     if (node->prev) {
  793.         search = node->prev;
  794.         while (search && search->type == SPACE)
  795.             search = search->prev;
  796.         if (search && search->type == SPECIAL)
  797.             return (search->flags);
  798.     }
  799.     if (node->next) {
  800.         search = node->next;
  801.         while (search && search->type == SPACE)
  802.             search = search->next;
  803.         /* Hinter der Node ist ein # (ToString) ohne Bedeutung */
  804.         if (search && search->type == SPECIAL
  805.             && search->flags == KILLSPACES)
  806.             return (KILLSPACES);
  807.     }
  808.     return (NONE);
  809. }
  810.  
  811. /* FindBracket - sucht das passende Gegenstueck zu der (, auf die Node zeigt */
  812. /*               dabei werden verschachtelte Klammern beachtet               */
  813. struct strnode *FindBracket(struct strnode *node)
  814. {
  815.  
  816.     if (DEBUG & 32)
  817.         puts("FindBracket");
  818.  
  819.  
  820.     if (node && node->next && node->type == NORMAL && node->str[0] == '(') {
  821.         do {
  822.             node = node->next;
  823.             if (node && node->type == NORMAL) {
  824.                 if (node->str[0] == ')')
  825.                     return (node);
  826.                 if (node->str[0] == '(')
  827.                     node = FindBracket(node);
  828.             }
  829.         } while (node);
  830.         return (NULL);
  831.     } else
  832.         return (NULL);
  833. }
  834.  
  835. /* CloneArg - gibt eine Liste zurueck, die das n. Argument des Makros enthaelt */
  836. struct strnode *CloneArg(struct strnode *list, int n, int *error)
  837. {
  838.     int argnum = 0;
  839.     struct strnode *start;
  840.  
  841.     if (error)
  842.         *error = OK;
  843.  
  844.     if (list) {
  845.         if (DEBUG & 32)
  846.             printf("CloneArg\n");
  847.         if (list->type == PP_IDENT)
  848.             list = list->next;
  849.         while (list && list->type == SPACE)
  850.             list = list->next;
  851.  
  852.         if (list && list->type == NORMAL && list->str[0] == '(') {
  853.             list = list->next;  /* Skip ( */
  854.  
  855.             if (DEBUG & 32)
  856.                 printf("- IDENT skipped, ( found\n");
  857.  
  858.             while (list && (argnum < n)) {
  859.                 if (list->type == NORMAL) {
  860.                     if (list->str[0] == ')')
  861.                         list = NULL;
  862.                     if (list && list->str[0] == '(')
  863.                         list = (FindBracket(list))->next;
  864.                     if (list && list->str[0] == ',')
  865.                         argnum++;
  866.                 }
  867.                 if (list)
  868.                     list = list->next;
  869.             }
  870.  
  871.             while (list && list->type == SPACE)
  872.                 list = list->next;
  873.  
  874.             if (list) {
  875.                 if (list->type == NORMAL && (list->str[0] == ')' || list->str[0] == ',')) {     /* HIER evtl. ein Space erzeugen */
  876.                     return (NULL);
  877.                 }
  878.                 start = list;
  879.             } else {
  880.                 if (error)
  881.                     *error = ARG_EXPECTED;
  882.                 return (NULL);
  883.             }
  884.  
  885.             if (DEBUG & 32)
  886.                 printf("- Okay, Arg-Start found: %s\n", start->str);
  887.  
  888.             while (list && (argnum == n)) {
  889.                 if (list->type == NORMAL) {
  890.                     switch (list->str[0]) {
  891.                     case ')':
  892.                     case ',':
  893.                         argnum++;
  894.                         list = list->prev;
  895.                         break;
  896.                     case '(':
  897.                         list = FindBracket(list);
  898.                     default:
  899.                         if (list)
  900.                             list = list->next;
  901.                         break;
  902.                     }
  903.                 } else if (list)
  904.                     list = list->next;
  905.             }
  906.  
  907.             while (list && list->type == SPACE)
  908.                 list = list->prev;
  909.  
  910.             if (DEBUG & 32)
  911.                 printf("- Okay, Arg-End found: %s\n", list->str);
  912.             return (CloneStrList(start, list));
  913.  
  914.         } else {
  915.             if (error)
  916.                 *error = ARG_EXPECTED;
  917.             return (NULL);
  918.         }
  919.     } else
  920.         return (NULL);
  921. }
  922.  
  923. /* ExpandArgMakro - ersetzt ein Makro mit Argumenten */
  924. int ExpandArgMakro(struct mnode *makro, struct strnode **list,
  925.                    struct strnode **pos)
  926. {
  927.     struct strnode *clone, *temp, *temp1, *arg, *new;
  928.     struct strnode *prev, *next;
  929.     struct mnode *prevmakro;
  930.     char *newstr;
  931.     int spec, len, x;
  932.  
  933.     clone = CloneStrList(makro->tokenlist, NULL);
  934.     if (!clone)
  935.         return (OUT_OF_MEM);
  936.  
  937.     if (DEBUG & 32)
  938.         printf("ExpandArgMakro - Clone build.\n");
  939.  
  940.     temp = clone;
  941.     while (temp) {
  942.         if (temp->type == ARGUMENT) {
  943.             arg = CloneArg(*pos, temp->number, &x);
  944.             if (!arg) {
  945.                 DelStrList(&clone);
  946.                 return (x);
  947.             }
  948.             if (DEBUG & 32) {
  949.                 printf("ARGUMENT:\n");
  950.                 PrintTL(arg);
  951.                 printf("Argument found - ");
  952.             }
  953.             if (spec = NextToSpecial(temp)) {
  954.                 /* nicht expandieren, nur einsetzen */
  955.                 if (spec == TOSTRING) {
  956.  
  957.                     if (DEBUG & 32)
  958.                         printf("next to #\n");
  959.                     /* als String einsetzen */
  960.                     new = (struct strnode *) malloc(sizeof(struct strnode));
  961.                     if (!new) {
  962.                         DelStrList(&clone);
  963.                         DelStrList(&arg);
  964.                         return (OUT_OF_MEM);
  965.                     }
  966.                     len = ListStrLen(arg);
  967.                     newstr = (char *) malloc(len + 1);
  968.                     if (!newstr) {
  969.                         DelStrList(&clone);
  970.                         DelStrList(&arg);
  971.                         if (new)
  972.                             free(new);
  973.                         return (OUT_OF_MEM);
  974.                     }
  975.                     CopyList2StrStr(arg, newstr);
  976.                     DelStrList(&arg);
  977.                     new->len = len + 2;
  978.                     new->flags = new->number = 0;
  979.                     new->type = PP_STR;
  980.                     new->str = newstr;
  981.  
  982.                     prev = temp->prev;
  983.                     next = temp->next;
  984.                     DelStrNode(NULL, temp);     /* Argument */
  985.  
  986.                     while (prev && prev->type == SPACE) {
  987.                         temp = prev->prev;
  988.                         DelStrNode(&clone, prev);
  989.                         prev = temp;
  990.                     }
  991.  
  992.                     if (prev && prev->type == SPECIAL && prev->flags == TOSTRING) {
  993.                         temp = prev->prev;
  994.                         DelStrNode(&clone, prev);
  995.                         prev = temp;
  996.                     } else
  997.                         ierror(0);
  998.  
  999.                     new->prev = prev;
  1000.                     if (prev)
  1001.                         prev->next = new;
  1002.                     else
  1003.                         clone = new;
  1004.                     new->next = next;
  1005.                     if (next)
  1006.                         next->prev = new;
  1007.                     temp = new;
  1008.                 } else {
  1009.                     /* Einfach nur einsetzen */
  1010.                     if (DEBUG & 32)
  1011.                         printf("next to ##\n");
  1012.                     prev = temp->prev;
  1013.                     next = temp->next;
  1014.                     DelStrNode(NULL, temp);
  1015.                     arg->prev = prev;
  1016.                     if (prev)
  1017.                         prev->next = arg;
  1018.                     else
  1019.                         clone = arg;
  1020.                     while (arg->next)
  1021.                         arg = arg->next;
  1022.                     arg->next = next;
  1023.                     if (next)
  1024.                         next->prev = arg;
  1025.                     temp = arg;
  1026.                 }
  1027.             } else {
  1028.                 /* expandieren und einsetzen */
  1029.                 if (DEBUG & 32)
  1030.                     printf("normal arg\n");
  1031.                 if (x = ExpandList(&arg)) {
  1032.                     DelStrList(&clone);
  1033.                     DelStrList(&arg);
  1034.                     return (x);
  1035.                 }
  1036.                 if (DEBUG & 32) {
  1037.                     printf("expanded arg:\n");
  1038.                     PrintTL(arg);
  1039.                 }
  1040.                 prev = temp->prev;
  1041.                 next = temp->next;
  1042.                 DelStrNode(NULL, temp);
  1043.                 arg->prev = prev;
  1044.                 if (prev)
  1045.                     prev->next = arg;
  1046.                 else
  1047.                     clone = arg;
  1048.                 while (arg->next)
  1049.                     arg = arg->next;
  1050.                 arg->next = next;
  1051.                 if (next)
  1052.                     next->prev = arg;
  1053.                 temp = arg;
  1054.             }                   /* of N2Special */
  1055.         }
  1056.         if (temp)
  1057.             temp = temp->next;
  1058.     }
  1059.  
  1060.     if (DEBUG & 32)
  1061.         printf("Arguments expanded.\n");
  1062.  
  1063.     temp = clone;
  1064.     while (temp) {
  1065.         if (temp->type == SPECIAL && temp->flags == KILLSPACES) {
  1066.             prev = temp->prev;
  1067.             next = temp->next;
  1068.             if ((prev->type == PP_IDENT || prev->type == NUMBER)) {
  1069.                 switch (next->type) {
  1070.                 case NUMBER:    /* merge -> ident */
  1071.                 case PP_IDENT:
  1072.                     RemStrNode(&clone, next);
  1073.                     MergeStrNodes(prev, next);
  1074.                     next = temp->next;
  1075.                     /* next will now be deleted and prev->str will be */
  1076.                     /* the joined strings from prev&next */
  1077.                 default:        /* no merge / del ## */
  1078.                     DelStrNode(&clone, temp);
  1079.                     temp = next;
  1080.                     break;
  1081.                 }               /* of switch */
  1082.             } else {
  1083.                 DelStrNode(&clone, temp);
  1084.                 temp = next;
  1085.             }
  1086.         }
  1087.         if (temp)
  1088.             temp = temp->next;
  1089.     }
  1090.  
  1091.     /* 'makro' aus mlist ausklinken */
  1092.     prevmakro = makro->prev;
  1093.     RemMakroNode(&mlist, makro);
  1094.  
  1095.     /* alles expandieren */
  1096.     if (!(x = ExpandList(&clone))) {
  1097.         /* akt. StrNode durch clone-Liste ersetzen */
  1098.  
  1099.         if (DEBUG & 32) {
  1100.             printf("Complete Makro expanded\n");
  1101.             PrintTL(clone);
  1102.         }
  1103.         /* clone anstelle von pos in list einsetzen */
  1104.         prev = (*pos)->prev;
  1105.         next = (*pos)->next;
  1106.  
  1107.         DelStrNode(NULL, *pos);
  1108.  
  1109. #ifdef bla
  1110.         while (next && next->type == SPACE) {
  1111.             temp = next->next;
  1112.             DelStrNode(NULL, next);     /* SPACE zwischen Makro und Args loeschen */
  1113.             next = temp;
  1114.         }
  1115. #endif
  1116.         while (next && next->type == SPACE)
  1117.             next = next->next;
  1118.         /* SPACE hinter Makro ueberspringen */
  1119.  
  1120.         if (next && next->type == NORMAL && next->str[0] == '(') {
  1121.             temp = next;
  1122.             next = FindBracket(temp);
  1123.             if (next)
  1124.                 next = next->next;
  1125.             do {
  1126.                 temp1 = temp->next;
  1127.                 DelStrNode(NULL, temp);         /* ARG-List hinter Makro loeschen */
  1128.                 temp = temp1;
  1129.             } while (temp != next);
  1130.         } else {
  1131.             ierror(0);
  1132.         }
  1133.  
  1134.  
  1135.         /* vor clone ein SPACE einsetzen, wenn nicht PREV==SPACE */
  1136. /*vb:   hier !prev|| wegen Enforcerhit eingesetzt; waere prev&& besser? */
  1137.         if (!prev || prev->type != SPACE) {
  1138.             if (temp = AllocSpace()) {
  1139.                 temp->next = clone;
  1140.                 if (clone)
  1141.                     clone->prev = temp;
  1142.                 clone = temp;
  1143.             }
  1144.         }
  1145.         clone->prev = prev;
  1146.         if (prev)
  1147.             prev->next = clone;
  1148.         else
  1149.             *list = clone;
  1150.  
  1151.         while (clone->next)
  1152.             clone = clone->next;
  1153.         /* nach clone ein SPACE einsetzen, wenn nicht NEXT==SPACE */
  1154. /*vb:   hier !next|| wegen Enforcerhit eingesetzt; waere next&& besser? */
  1155.         if (!next || next->type != SPACE) {
  1156.             if (temp = AllocSpace()) {
  1157.                 temp->prev = clone;
  1158.                 if (clone)
  1159.                     clone->next = temp;
  1160.                 clone = temp;
  1161.             }
  1162.         }
  1163.         *pos = clone;
  1164.         clone->next = next;
  1165.         if (next)
  1166.             next->prev = clone;
  1167.  
  1168.         /* 'makro' wieder einsetzen */
  1169.         InsertMakroNode(&mlist, makro, prevmakro);
  1170.         return (OK);
  1171.     } else {
  1172.         InsertMakroNode(&mlist, makro, prevmakro);
  1173.         return (x);
  1174.     }
  1175.  
  1176. }
  1177.  
  1178. /* ExpandList - ersetzt alle Makros in der Liste */
  1179. int ExpandList(struct strnode **list)
  1180. {
  1181.     struct mnode *found, *before;
  1182.     struct strnode *clone, *beforestr, *afterstr, *listtemp, *temp2,
  1183.     *temp3;
  1184.     int result = OK;
  1185.  
  1186.     if (DEBUG & 32)
  1187.         puts("ExpandList");
  1188.  
  1189.  
  1190.     listtemp = *list;
  1191.     while (listtemp) {
  1192.  
  1193.         if (listtemp->type == PP_IDENT) {
  1194.  
  1195.             found = FindMakroNode(mlist, listtemp->str, 0);
  1196.             if (found) {
  1197. /*vb: merken, ob mind. ein Makro expandiert wurde   */
  1198.                 did_expand = 1;
  1199.                 if (found->flags & PARAMETER) {
  1200.                     /* Makro mit Argument(en) */
  1201.                     if (DEBUG & 32)
  1202.                         printf("Makro with args\n");
  1203.  
  1204.                     temp2 = listtemp->next;
  1205.                     while (temp2 && temp2->type == SPACE)
  1206.                         temp2 = temp2->next;
  1207.  
  1208.                     if (temp2 && temp2->type == NORMAL && temp2->str[0] == '(')
  1209.                         if (result = ExpandArgMakro(found, list, &listtemp))
  1210.                             return (result);
  1211.  
  1212.                 } else {
  1213.  
  1214.                     /* Makro ohne Argument */
  1215.  
  1216.                     /* ExpandNormMakro - expandiert ein Makro ohne Argumente */
  1217.                     /* Parameter: s.o. */
  1218.  
  1219.                     if (found->flags & FUNCTION) {
  1220.                         clone = DoMakroFunction(found);
  1221.                     } else {
  1222.                         clone = CloneStrList(found->tokenlist, NULL);
  1223.                     }
  1224.                     if (!clone)
  1225.                         return (OUT_OF_MEM);
  1226.                     /* akt. MakroNode ausklinken um rekursive Exp. zu verhindern */
  1227.                     before = found->prev;
  1228.                     RemMakroNode(&mlist, found);
  1229.                     if (!(result = ExpandList(&clone))) {
  1230.                         /* akt. StrNode durch clone-Liste ersetzen */
  1231.                         beforestr = listtemp->prev;
  1232.                         afterstr = listtemp->next;
  1233.                         DelStrNode(NULL, listtemp);
  1234.                         listtemp = afterstr;
  1235.                         clone->prev = beforestr;
  1236.                         if (beforestr)
  1237.                             beforestr->next = clone;
  1238.                         else
  1239.                             *list = clone;
  1240.                         while (clone->next)
  1241.                             clone = clone->next;
  1242.                         clone->next = afterstr;
  1243.                         if (afterstr)
  1244.                             afterstr->prev = clone;
  1245.                         /* akt. Makronode wieder einsetzen */
  1246.                         InsertMakroNode(&mlist, found, before);
  1247.                     } else {
  1248.                         /* akt. Makronode wieder einsetzen */
  1249.                         InsertMakroNode(&mlist, found, before);
  1250.                         return (result);
  1251.                     }
  1252.                 }
  1253.             }
  1254.         }
  1255.         if (listtemp)
  1256.             listtemp = listtemp->next;
  1257.     }
  1258.  
  1259.     return (OK);
  1260. }
  1261.  
  1262.  
  1263. /* ParseIdentifier - parsed den Input-Define-String und haengt das Makro */
  1264. /*                   in die Liste */
  1265.  
  1266. struct mnode *ParseIdentifier(char *str)
  1267. {
  1268.     int x, numargs = 0, flags = 0, len = 0;
  1269.     char *name = NULL, *args = NULL, *token = NULL, *temp, *temp2, *argtemp;
  1270.     struct mnode *newmakro, *found;
  1271.     struct strnode *tokenlist = NULL, *templist, *arglist = NULL, *templist2;
  1272.     struct strnode *next, *prev;
  1273.  
  1274.     if (DEBUG & 32)
  1275.         puts("ParseIdentifier");
  1276.  
  1277. /*vb: casts eingefuegt  */
  1278.     while (isspace((unsigned char) *str)) {
  1279.         str++;
  1280.     }
  1281.     if (!(isalpha((unsigned char) *str) || *str == '_')) {
  1282.         error(178);
  1283.         return (0);
  1284.     }
  1285.     temp = str;
  1286.     while (isalnum((unsigned char) *temp) || (*temp == '_')) {
  1287.         temp++;
  1288.         len++;
  1289.     }
  1290.  
  1291.     /* auf schon vorhandene (evtl. FESTE) Definition suchen */
  1292.     found = FindMakroNode(mlist, str, len);
  1293.     if (found && (found->flags & NOREDEF)) {
  1294.         error(179);
  1295.         return (0);
  1296.     }
  1297. /*vb:   */
  1298.     if (1) {
  1299.         /* Okay, ist egal, wie das alte Makro aussah */
  1300.  
  1301. /*vb:   */
  1302.         if (found && !(c_flags[15] & USEDFLAG)) {
  1303.             error(197);
  1304.         }
  1305.         temp = name = (char *) malloc(len + 1);         /* Speicher fuer Name-String belegen */
  1306.         if (!name) {
  1307.             error(196);
  1308.             return (0);
  1309.         }
  1310.         for (x = 0; x < len; x++) {
  1311.             *temp++ = *str++;
  1312.         }                       /* Namen kopieren */
  1313.         *temp = 0;
  1314.  
  1315.         if (*str == '(') {
  1316.             flags |= PARAMETER;
  1317.             str++;              /* jump over '(' */
  1318.             temp = str;
  1319.             len = 0;
  1320. /*vb: casts eingefuegt  */
  1321.             while (*temp && (*temp != ')'))
  1322.                 if (!(isspace((unsigned char) *temp))) {
  1323.                     len++;
  1324.                     temp++;
  1325.                 } else {
  1326.                     temp++;
  1327.                 }
  1328.             if (*temp == 0) {
  1329.                 error(180);
  1330.                 if (name)
  1331.                     free(name);
  1332.                 return (0);
  1333.             }
  1334.             args = temp = (char *) malloc(len + 1);
  1335.             if (!args) {
  1336.                 error(196);
  1337.                 if (name)
  1338.                     free(name);
  1339.                 return (0);
  1340.             }
  1341.             for (x = 0; x < len;)
  1342.                 if (!(isspace((unsigned char) *str))) {
  1343.                     x++;
  1344.                     *temp++ = *str++;
  1345.                 } else {
  1346.                     str++;
  1347.                 }
  1348.             *temp = 0;
  1349.             str++;              /* jump over ')' */
  1350.  
  1351.             /* Argumentliste parsen und auf Fehler pruefen */
  1352.             temp = args;
  1353.             while (*temp && (isalpha((unsigned char) *temp) || *temp == '_')) {
  1354.                 temp++;
  1355.                 while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  1356.                     temp++;
  1357.                 }
  1358.                 if (!(*temp) || *temp == ',') {
  1359.                     numargs++;
  1360.                     if ((*temp == ',') && (isalpha((unsigned char) *(temp + 1)) || *(temp + 1) == '_'))
  1361.                         temp++;
  1362.                 }
  1363.             }
  1364.             if (*temp) {
  1365.                 if (args)
  1366.                     free(args);
  1367.                 if (name)
  1368.                     free(name);
  1369.                 if (*temp == ',') {
  1370.                     error(181);
  1371.                 } else {
  1372.                     error(182);
  1373.                 }
  1374.                 return (0);
  1375.             }
  1376.         }
  1377.         while (isspace((unsigned char) *str))
  1378.             str++;              /* Skip Spaces */
  1379.         /* HIER: pruefen, ob tokenlist erstellt werden konnte (leere tokenlist->ok) */
  1380.         tokenlist = Str2List(str);
  1381.         if (DEBUG & 32)
  1382.             printf(" - build TokenList\n");
  1383.         templist = tokenlist;
  1384.         while (templist) {
  1385.             if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) {
  1386.  
  1387.                 if ((templist->next) && (templist->next->type == NORMAL)
  1388.                     && (!strcmp(templist->next->str, "#"))) {
  1389.                     /* ## KILLSPACES */
  1390.                     if ((templist->prev) && (templist->next->next)) {
  1391.                         templist->type = SPECIAL;
  1392.                         templist->flags = KILLSPACES;
  1393.                         DelStrNode(&tokenlist, templist->next);
  1394.                     } else {
  1395.                         error(183);
  1396.                         if (name)
  1397.                             free(name);
  1398.                         if (args)
  1399.                             free(args);
  1400.                         if (tokenlist)
  1401.                             DelStrList(&tokenlist);
  1402.                         return (0);
  1403.                     }
  1404.                 }
  1405.             }
  1406.             templist = templist->next;
  1407.         }
  1408.  
  1409.         /* Token parsen/kopieren */
  1410.         if ((flags & PARAMETER)) {      /* Argumente parsen */
  1411.             arglist = NULL;
  1412.             temp = temp2 = args;
  1413.             while (*temp) {
  1414.                 len = 0;
  1415.                 while (*temp && *temp != ',') {
  1416.                     temp++;
  1417.                     len++;
  1418.                 }
  1419.                 if (*temp == ',')
  1420.                     temp++;
  1421.                 argtemp = (char *) malloc(len + 1);
  1422.                 if (!argtemp) {
  1423.                     error(196);
  1424.                     if (name)
  1425.                         free(name);
  1426.                     if (args)
  1427.                         free(args);
  1428.                     if (arglist)
  1429.                         DelStrList(&arglist);
  1430.                     if (tokenlist)
  1431.                         DelStrList(&tokenlist);
  1432.                     return (0);
  1433.                 }
  1434.                 strncpy(argtemp, temp2, len);
  1435.                 temp2 = temp;
  1436.                 *(argtemp + len) = 0;
  1437.                 AddStrNodeBehind(&arglist, NULL, argtemp);
  1438.             }
  1439.             templist = tokenlist;
  1440.             while (templist) {
  1441.                 if (templist->type == PP_IDENT) {
  1442.                     x = 0;
  1443.                     templist2 = arglist;
  1444.                     while (templist2) {
  1445.                         if (!strcmp(templist->str, templist2->str)) {
  1446.                             templist->type = ARGUMENT;
  1447.                             templist->number = x;
  1448.                         }
  1449.                         x++;
  1450.                         templist2 = templist2->next;
  1451.                     }
  1452.                 }
  1453.                 templist = templist->next;
  1454.             }
  1455.             DelStrList(&arglist);
  1456.             if (DEBUG & 32)
  1457.                 printf(" - Arguments found.\n");
  1458.             /* #-Specials korrigieren, nachdem die Argumente erkannt wurden */
  1459.             templist = tokenlist;
  1460.             while (templist) {
  1461.                 if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) {
  1462.                     if ((templist->next) && (templist->next->type == ARGUMENT)) {
  1463.                         templist->type = SPECIAL;
  1464.                         templist->flags = TOSTRING;
  1465.                     } else {
  1466.                         error(184);
  1467.                         if (name)
  1468.                             free(name);
  1469.                         if (args)
  1470.                             free(args);
  1471.                         if (arglist)
  1472.                             DelStrList(&arglist);
  1473.                         if (tokenlist)
  1474.                             DelStrList(&tokenlist);
  1475.                         return (0);
  1476.                     }
  1477.                 }
  1478.                 templist = templist->next;
  1479.             }
  1480.             if (DEBUG & 32)
  1481.                 printf(" - Special-# corrected.\n");
  1482.         } else {                /* Token kopieren */
  1483.             temp = str;
  1484.             len = 0;
  1485.             while ((*temp) && (*temp != '\n')) {
  1486.                 temp++;
  1487.                 len++;
  1488.             }
  1489.             temp = token = (char *) malloc(len + 1);
  1490.             if (!token) {
  1491.                 error(196);
  1492.                 if (name)
  1493.                     free(name);
  1494.                 if (args)
  1495.                     free(args);
  1496.                 if (tokenlist)
  1497.                     DelStrList(&tokenlist);
  1498.                 return (0);
  1499.             }
  1500.             for (x = 0; x < len; x++) {
  1501.                 *temp++ = *str++;
  1502.             }
  1503.             *temp = 0;
  1504.         }
  1505.  
  1506.  
  1507.         templist = tokenlist;
  1508.         while (templist) {
  1509.             if (templist->type == SPECIAL && templist->flags == KILLSPACES) {
  1510.                 next = templist->next;
  1511.                 prev = templist->prev;
  1512.  
  1513.                 /* Kill Spaces before/after ## */
  1514.                 while (prev && prev->type == SPACE) {
  1515.                     templist2 = prev->prev;
  1516.                     DelStrNode(&tokenlist, prev);
  1517.                     prev = templist2;
  1518.                 }
  1519.                 while (next && next->type == SPACE) {
  1520.                     templist2 = next->next;
  1521.                     DelStrNode(&tokenlist, next);
  1522.                     next = templist2;
  1523.                 }
  1524.                 if ((!next) || (!prev))
  1525.                     ierror(0);
  1526.  
  1527.                 if (next->type != ARGUMENT && prev->type != ARGUMENT) {
  1528.                     if ((prev->type == PP_IDENT || prev->type == NUMBER)) {
  1529.                         switch (next->type) {
  1530.                         case NUMBER:    /* merge -> ident */
  1531.                         case PP_IDENT:
  1532.                             RemStrNode(&tokenlist, next);
  1533.                             MergeStrNodes(prev, next);
  1534.                             next = templist->next;
  1535.                             /* next will now be deleted and prev->str will be */
  1536.                             /* the joined strings from prev&next */
  1537.                         default:        /* no merge / del ## */
  1538.                             DelStrNode(&tokenlist, templist);
  1539.                             templist = next;
  1540.                             break;
  1541.                         }       /* of switch */
  1542.                     } else {
  1543.                         DelStrNode(&tokenlist, templist);
  1544.                         templist = next;
  1545.                     }
  1546.                 }
  1547.             }
  1548.             if (templist)
  1549.                 templist = templist->next;
  1550.         }
  1551.  
  1552.  
  1553. /* erst HIER bei allowredefinition=0 abfragen ?? */
  1554.  
  1555.         if (newmakro = (struct mnode *) malloc(sizeof(struct mnode))) {
  1556.             newmakro->name = name;
  1557.             newmakro->args = args;
  1558.             newmakro->token = token;
  1559.             newmakro->tokenlist = tokenlist;
  1560.             newmakro->flags = flags;
  1561.             newmakro->funcnum = 0;
  1562.             AddMakroNode(&mlist, newmakro);
  1563.         } else {
  1564.             error(196);
  1565.             if (name)
  1566.                 free(name);
  1567.             if (token)
  1568.                 free(token);
  1569.             if (args)
  1570.                 free(args);
  1571.             if (tokenlist)
  1572.                 DelStrList(&tokenlist);
  1573.         }
  1574.         return (newmakro);
  1575.  
  1576.     } else {
  1577. /*vb:   das ist irgendwie Unsinn hier, glaube ich   */
  1578.         ierror(0);
  1579.         /* HIER: ueberpruefen, ob Macrodefinitionen uebereinstimmen, sonst Error */
  1580.         if (*temp == '(') {
  1581.             if (found->flags & PARAMETER) {
  1582.                 temp++;         /* skip ( */
  1583.  
  1584.  
  1585.  
  1586.             } else {
  1587.                 error(185);
  1588.                 return (NULL);
  1589.             }
  1590.         }
  1591.         /* HIER nur noch tokenlisten vergleichen */
  1592.  
  1593.     }
  1594.     if (DEBUG & 32)
  1595.         printf("ParseIdent falls of\n");
  1596. }
  1597.  
  1598.  
  1599. /* PreParse - 3-Zeichen-Folgen ersetzen, \+CR Zeilen anhaengen, usw.. */
  1600.  
  1601. int PreParse()
  1602. {
  1603.     char *src, *dest, *dest2;
  1604.     int slen, dlen = 0;
  1605.     int cat = 0;                /*vb: um zu merken, ob Zeilen mit \ verbunden werden */
  1606.     dest2 = string;
  1607.  
  1608.     if (DEBUG & 32)
  1609.         puts("PreParse");
  1610.  
  1611.  
  1612.     if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) {
  1613.         if (cmtnesting)
  1614.             error(186);
  1615. /*vb:   */
  1616. /*      if(ifstatus[incnesting]) error(186); */
  1617. /*      ifnesting--; */
  1618.         if (DEBUG & 32)
  1619.             printf("-- end of file  ifnesting-1:%d\n\n", incnesting);
  1620.         if (incnesting) {
  1621.             fclose(in[incnesting]);
  1622.             incnesting--;
  1623.             return (pp_nextline());
  1624.         } else
  1625.             return (0);
  1626.     } else if (DEBUG & 32)
  1627.         printf("gets1:%s\n", ppstring);         /*vb: */
  1628.  
  1629.     if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) {
  1630.         error(177);
  1631.         return (0);
  1632.     }
  1633.     zn[incnesting]++;
  1634.     linenr = zn[incnesting];
  1635.  
  1636.     do {
  1637.         /* Zeilen einlesen, bis kein Kommentar mehr */
  1638.  
  1639.         /* Zeilen einlesen bis kein \ mehr am Ende */
  1640.         do {
  1641.             /* Source-String an Dest-String anhaengen und ??x-Folgen ersetzen */
  1642. /*vb: das killt sonst das angehaengte wieder   */
  1643.             if (cat == 0) {
  1644.                 dest = src = ppstring;
  1645.                 slen = 0;
  1646.             }
  1647.             do {
  1648.                 if (*src != '\n') {
  1649.  
  1650.                     if ((*src == '?') && (*(src + 1) == '?') && !(c_flags[16] & USEDFLAG)) {
  1651.                         switch (*(src + 2)) {
  1652.                         case '=':
  1653.                             *dest++ = '#';
  1654.                             src += 2;
  1655.                             break;
  1656.                         case '/':
  1657.                             *dest++ = '\\';
  1658.                             src += 2;
  1659.                             break;
  1660.                         case '\'':
  1661.                             *dest++ = '^';
  1662.                             src += 2;
  1663.                             break;
  1664.                         case '(':
  1665.                             *dest++ = '[';
  1666.                             src += 2;
  1667.                             break;
  1668.                         case ')':
  1669.                             *dest++ = ']';
  1670.                             src += 2;
  1671.                             break;
  1672.                         case '!':
  1673.                             *dest++ = '|';
  1674.                             src += 2;
  1675.                             break;
  1676.                         case '<':
  1677.                             *dest++ = '{';
  1678.                             src += 2;
  1679.                             break;
  1680.                         case '>':
  1681.                             *dest++ = '}';
  1682.                             src += 2;
  1683.                             break;
  1684.                         case '-':
  1685.                             *dest++ = '~';
  1686.                             src += 2;
  1687.                             break;
  1688.                         default:
  1689.                             *dest++ = *src;
  1690.                             break;
  1691.                         }       /* of switch */
  1692.                     } else {
  1693.                         *dest++ = *src;
  1694.                     }
  1695.  
  1696.                     if (slen < MAXPPINPUT) {
  1697.                         slen++;
  1698.                     } else {
  1699.                         error(177);
  1700.                         return (0);
  1701.                     }
  1702.                 }
  1703.             } while (*src++);
  1704.  
  1705.             src = dest;
  1706.             /* dest->lastchar+2/NULL+1 (dest-1)-> 0 (dest-2)->lastchar */
  1707.             if (*(dest - 2) == '\\') {
  1708.                 /*vb: sollte das slen statt dlen sein?  */
  1709.                 if (fgets(src, MAXPPINPUT - dlen, in[incnesting])) {
  1710.                     if (DEBUG & 32)
  1711.                         printf("gets2:%s\n", src);      /*vb:  */
  1712. /* Hier auf LF+0 abfragen */
  1713.                     dest -= 2;
  1714.                     zn[incnesting]++;
  1715.                     cat = 1;    /*vb: merken, dass Zeilen verbunden wurden */
  1716.                 }
  1717.             }
  1718.         } while (*dest == '\\');
  1719.  
  1720.         src = ppstring;
  1721.         while (*src) {
  1722.             /* ' Strings ueberlesen */
  1723.             if ((*src == '\'') && (!cmtnesting)) {
  1724.                 if (dlen < MAXINPUT) {
  1725.                     *dest2++ = *src++;
  1726.                     dlen++;
  1727.                 } else {
  1728.                     error(177);
  1729.                     return (0);
  1730.                 }
  1731.                 while (*src && *src != '\'') {
  1732.                     if (*src == '\\') {
  1733.                         *dest2++ = *src++;
  1734.                         dlen++;
  1735.                     };
  1736.                     if (dlen < MAXINPUT) {
  1737.                         *dest2++ = *src++;
  1738.                         dlen++;
  1739.                     } else {
  1740.                         error(177);
  1741.                         return (0);
  1742.                     }
  1743.                 }
  1744.                 if (dlen < MAXINPUT) {
  1745.                     *dest2++ = *src++;
  1746.                     dlen++;
  1747.                 } else {
  1748.                     error(177);
  1749.                     return (0);
  1750.                 }
  1751.             }
  1752.             /* " Strings ueberlesen */
  1753.             if ((*src == '\"') && (!cmtnesting)) {
  1754.                 *dest2++ = *src++;
  1755.                 dlen++;
  1756.                 while (*src && *src != '\"') {
  1757.                     if (*src == '\\') {
  1758.                         *dest2++ = *src++;
  1759.                         dlen++;
  1760.                     };
  1761.                     if (dlen < MAXINPUT) {
  1762.                         *dest2++ = *src++;
  1763.                         dlen++;
  1764.                     } else {
  1765.                         error(177);
  1766.                         return (0);
  1767.                     }
  1768.                 }
  1769.                 if (dlen < MAXINPUT) {
  1770.                     *dest2++ = *src++;
  1771.                     dlen++;
  1772.                 } else {
  1773.                     error(177);
  1774.                     return (0);
  1775.                 }
  1776.             }
  1777.             /* Kommentare weglassen */
  1778.             if ((*src == '/') && (*(src + 1) == '*')) {
  1779.                 src += 2;
  1780.                 if (dlen < MAXINPUT) {
  1781.                     *dest2++ = ' ';
  1782.                     dlen++;
  1783.                 } else {
  1784.                     error(177);
  1785.                     return (0);
  1786.                 }
  1787.                 if ((cmtnesting && (c_flags[13] & USEDFLAG)) || (!cmtnesting))
  1788.                     cmtnesting++;
  1789.                 else
  1790.                     error(198);
  1791.             } else {
  1792.                 if ((*src == '*') && (*(src + 1) == '/') && cmtnesting) {
  1793.                     src += 2;
  1794.                     cmtnesting--;
  1795.                 }
  1796.             }
  1797.  
  1798.             /* C++-Comment weglassen */
  1799.             if ((!cmtnesting) && (*src == '/') && (*(src + 1) == '/') && (c_flags[14] & USEDFLAG))
  1800.                 *src = 0;
  1801.  
  1802.             if (!cmtnesting) {
  1803.                 if (*src) {
  1804.                     *dest2++ = *src++;
  1805.                 }
  1806.                 if (dlen < MAXINPUT) {
  1807.                     dlen++;
  1808.                 } else {
  1809.                     error(177);
  1810.                     return (0);
  1811.                 }
  1812.             } else {
  1813.                 if (*src)
  1814.                     src++;
  1815.             }
  1816.         }
  1817.  
  1818.         if (cmtnesting) {
  1819.             if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) {
  1820.                 if (cmtnesting)
  1821.                     error(186);
  1822.                 if (incnesting) {
  1823.                     fclose(in[incnesting]);
  1824.                     incnesting--;
  1825.                     return (pp_nextline());
  1826.                 } else
  1827.                     return (0);
  1828.             } else if (DEBUG & 32)
  1829.                 printf("gets2:%s\n", ppstring);         /*vb:   */
  1830.  
  1831.             if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) {
  1832.                 error(177);
  1833.                 return (0);
  1834.             }
  1835.             zn[incnesting]++;
  1836.         }
  1837.     } while (cmtnesting);
  1838.  
  1839. /*vb: das ueberschreibt den Speicher */
  1840. #if 0
  1841.     *dest2-- = 0;
  1842.     while (isspace(*dest2))
  1843.         *dest2-- = 0;           /* Spaces killen */
  1844. #endif
  1845.  
  1846. /*vb: hoffe, das ist besser */
  1847.     *dest2 = 0;
  1848.     while (dest2 > string && isspace((unsigned char) *--dest2))
  1849.         *dest2 = 0;
  1850.  
  1851.  
  1852.     return (1);
  1853. }
  1854.  
  1855. /* **************** PreProcessor ***************** */
  1856.  
  1857. int pp_init(void)
  1858. {
  1859.     char *macroname;
  1860.     struct mnode *macronode;
  1861.  
  1862.     if (!(c_flags[6] & USEDFLAG))
  1863.         printf("%s\n", pp_version);
  1864.  
  1865.     incnesting = /*ifnesting= */ -1;    /*vb:  */
  1866.     cmtnesting = if_cnt = abs_if_cnt = 0;
  1867.     mlist = NULL;
  1868.     strlist = NULL;
  1869.  
  1870.     macroname = (char *) malloc(9);
  1871.     if (!macroname)
  1872.         return (0);
  1873.     strcpy(macroname, "__LINE__");
  1874.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1875.     if (!macronode) {
  1876.         if (macroname)
  1877.             free(macroname);
  1878.         return (0);
  1879.     }
  1880.     macronode->name = macroname;
  1881.     macronode->args = macronode->token = NULL;
  1882.     macronode->tokenlist = NULL;
  1883.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1884.     macronode->funcnum = FUNCLINE;
  1885.     AddMakroNode(&mlist, macronode);
  1886.  
  1887.     macroname = (char *) malloc(9);
  1888.     if (!macroname)
  1889.         return (0);
  1890.     strcpy(macroname, "__FILE__");
  1891.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1892.     if (!macronode) {
  1893.         if (macroname)
  1894.             free(macroname);
  1895.         DelMakroList(&mlist);
  1896.         return (0);
  1897.     }
  1898.     macronode->name = macroname;
  1899.     macronode->args = macronode->token = NULL;
  1900.     macronode->tokenlist = NULL;
  1901.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1902.     macronode->funcnum = FUNCFILE;
  1903.     AddMakroNode(&mlist, macronode);
  1904.  
  1905.     macroname = (char *) malloc(9);
  1906.     if (!macroname)
  1907.         return (0);
  1908.     strcpy(macroname, "__DATE__");
  1909.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1910.     if (!macronode) {
  1911.         if (macroname)
  1912.             free(macroname);
  1913.         DelMakroList(&mlist);
  1914.         return (0);
  1915.     }
  1916.     macronode->name = macroname;
  1917.     macronode->args = macronode->token = NULL;
  1918.     macronode->tokenlist = NULL;
  1919.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1920.     macronode->funcnum = FUNCDATE;
  1921.     AddMakroNode(&mlist, macronode);
  1922.  
  1923.     macroname = (char *) malloc(9);
  1924.     if (!macroname)
  1925.         return (0);
  1926.     strcpy(macroname, "__TIME__");
  1927.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1928.     if (!macronode) {
  1929.         if (macroname)
  1930.             free(macroname);
  1931.         DelMakroList(&mlist);
  1932.         return (0);
  1933.     }
  1934.     macronode->name = macroname;
  1935.     macronode->args = macronode->token = NULL;
  1936.     macronode->tokenlist = NULL;
  1937.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1938.     macronode->funcnum = FUNCTIME;
  1939.     AddMakroNode(&mlist, macronode);
  1940.  
  1941.     macroname = (char *) malloc(9);
  1942.     if (!macroname)
  1943.         return (0);
  1944.     strcpy(macroname, "__STDC__");
  1945.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1946.     if (!macronode) {
  1947.         if (macroname)
  1948.             free(macroname);
  1949.         DelMakroList(&mlist);
  1950.         return (0);
  1951.     }
  1952.     macronode->name = macroname;
  1953.     macronode->args = NULL;
  1954.     macroname = (char *) malloc(2);
  1955.     if (!macroname) {
  1956.         if (macronode->name)
  1957.             free(macronode->name);
  1958.         if (macronode)
  1959.             free(macronode);
  1960.         DelMakroList(&mlist);
  1961.         return (0);
  1962.     }
  1963.     strcpy(macroname, "1");
  1964.     macronode->token = macroname;
  1965.     macronode->tokenlist = Str2List(macroname);
  1966.     if (!macronode->tokenlist) {
  1967.         if (macronode->name)
  1968.             free(macronode->name);
  1969.         if (macronode->token)
  1970.             free(macronode->token);
  1971.         if (macronode)
  1972.             free(macronode);
  1973.         DelMakroList(&mlist);
  1974.         return (0);
  1975.     }
  1976.     macronode->flags = NODELETE;
  1977.     macronode->funcnum = 0;
  1978.     AddMakroNode(&mlist, macronode);
  1979.  
  1980.     return (1);
  1981. }
  1982.  
  1983.  
  1984. void pp_free(void)
  1985. {
  1986.     int i;
  1987.  
  1988.     if (DEBUG & 32)
  1989.         puts("pp_free");
  1990.  
  1991. /*vb: Schleifenindex korrekt gesetzt    */
  1992.     for (i = incnesting; i >= 0; i--)
  1993.         if (in[i])
  1994.             fclose(in[i]);
  1995.     DelMakroList(&mlist);
  1996.     DelStrList(&strlist);
  1997. }
  1998.  
  1999. int pp_include(char *f)
  2000. {
  2001.     if (DEBUG & 32)
  2002.         printf("trying to include %s\n", f);    /*vb:  */
  2003.  
  2004.     if (incnesting >= MAXINCNESTING - 1) {
  2005.         error(187);
  2006.         return (0);
  2007.     }
  2008. /*vb:   */
  2009. /*    if(ifnesting>=MAXIFNESTING-1)   {error("Too many nested #ifs or #includes",0);return(0);} */
  2010.     incnesting++;
  2011.     /*    ifnesting++; *//*vb:   */
  2012.     ifstatus[incnesting] = 0;   /*vb:   */
  2013.  
  2014.     if (DEBUG & 32)
  2015.         printf("-- include: ifnesting:%d ifstatus:0 \n\n", incnesting);
  2016.  
  2017.     in[incnesting] = fopen(f, "r");
  2018.     if (!in[incnesting]) {
  2019.         incnesting--;
  2020.         return (0);
  2021.     }
  2022.     filename[incnesting] = f;
  2023.     zn[incnesting] = linenr = 0;
  2024.     return (1);
  2025. }
  2026.  
  2027.  
  2028.  
  2029. /* ********************** Main-Function ******************* */
  2030. int pp_nextline(void)
  2031. {
  2032.     char *src, *dest, *temp;
  2033.     int complete_len, len, i, result;
  2034.     struct mnode *makro;
  2035.     struct strnode *linelist, *inclinelist;
  2036.  
  2037.     if (DEBUG & 32)
  2038.         puts("pp_nextline");
  2039.  
  2040.     dest = string;
  2041.     dest[0] = 0;
  2042.  
  2043.     /* String vorbereiten, 3ZF ersetzen, \-Zeilen anhaengen, Kommentare loeschen */
  2044.     if (!PreParse())
  2045.         return (0);
  2046.  
  2047.     /* Ueberpruefung auf PreProcessor-Commands */
  2048.     src = string;
  2049. /*vb: casts eingefuegt  */
  2050.     while (isspace((unsigned char) *src)) {
  2051.         src++;
  2052.     }                           /* SkipSpaces */
  2053.  
  2054.     if (*src == '#') {          /* #-Direktive gefunden */
  2055.         src++;                  /* # ueberlesen */
  2056.  
  2057.         while (isspace((unsigned char) *src)) {
  2058.             src++;
  2059.         }                       /* SkipSpaces */
  2060.  
  2061. /*vb:   Direktiven, die nichts mit #if etc. zu tun haben, nach hinten   */
  2062.  
  2063.  
  2064. /* IFDEF */
  2065.         if (!strncmp(src, "ifdef", 5)) {
  2066.             src += 5;
  2067.             abs_if_cnt++;       /*vb: */
  2068.             if (isspace((unsigned char) *src)) {
  2069.                 while (isspace((unsigned char) *src)) {
  2070.                     src++;
  2071.                 }
  2072.                 /* identifier suchen */
  2073.                 if (do_output) {
  2074. /*vb:   */
  2075. /*            if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */
  2076. /*            ifnesting++; */
  2077.                     temp = src;
  2078.                     len = 0;
  2079.                     while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
  2080.                         temp++;
  2081.                         len++;
  2082.                     }
  2083.                     makro = FindMakroNode(mlist, src, len);
  2084.                     if (DEBUG & 32)
  2085.                         printf("-- #ifdef found, ");
  2086.                     if (makro) {
  2087. /*vb:   */
  2088.                         ifstatus[incnesting] = 1;       /* Bedingung == TRUE */
  2089.                         if (DEBUG & 32)
  2090.                             printf(" condition '%s' found     (TRUE)\n", makro->name);
  2091.                     } else {
  2092. /*vb:   */
  2093.                         ifstatus[incnesting] = 2;       /* Bedingung == FALSE */
  2094.                         do_output = 0;
  2095.                         if (DEBUG & 32)
  2096.                             printf(" condition not found (FALSE)\n\n");
  2097.                     }
  2098.                 } else {
  2099.                     if_cnt++;
  2100.                     if (DEBUG & 32)
  2101.                         printf("-- #ifdef found and if_cnt increased\n\n");
  2102.                 }
  2103.                 string[0] = 0;  /*vb: yo   */
  2104.                 return (1);
  2105.             }
  2106.         }                       /* EO IFDEF */
  2107.         /* IFNDEF */
  2108.         if (!strncmp(src, "ifndef", 6)) {
  2109.             src += 6;
  2110.             abs_if_cnt++;       /*vb: */
  2111.             if (isspace((unsigned char) *src)) {
  2112.                 while (isspace((unsigned char) *src)) {
  2113.                     src++;
  2114.                 }
  2115.  
  2116.                 /* identifier suchen */
  2117.                 if (do_output) {
  2118. /*vb:   */
  2119. /*            if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */
  2120. /*            ifnesting++; */
  2121.                     temp = src;
  2122.                     len = 0;
  2123.                     while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
  2124.                         temp++;
  2125.                         len++;
  2126.                     }
  2127.                     if (DEBUG & 32)
  2128.                         printf("-- FindMakroNode: len=%d temp=%p\n", len, (void*)temp);
  2129.                     makro = FindMakroNode(mlist, src, len);
  2130.                     if (DEBUG & 32)
  2131.                         printf("-- #ifndef found, ");
  2132.                     if (!makro) {
  2133. /*vb:   */
  2134.                         ifstatus[incnesting] = 1;       /* Bedingung == TRUE (Makro not existing) */
  2135.                         if (DEBUG & 32)
  2136.                             printf(" condition not found  (TRUE)\n\n");
  2137.                     } else {
  2138. /*vb:   */
  2139.                         ifstatus[incnesting] = 2;       /* Bedingung == FALSE */
  2140.                         do_output = 0;
  2141.                         if (DEBUG & 32)
  2142.                             printf(" condition '%s'     found (FALSE)\n\n", makro->name);
  2143.                     }
  2144.                     /* HIER: string[0]=0; */
  2145.                 } else {
  2146.                     if_cnt++;
  2147.                     if (DEBUG & 32)
  2148.                         printf("-- #ifndef found and if_cnt increased\n\n");
  2149.                 }
  2150.                 string[0] = 0;  /*vb:   */
  2151.                 return (1);
  2152.             }
  2153.         }                       /* EO IFNDEF */
  2154.         /* IF */
  2155.         if (!strncmp(src, "if", 2)) {
  2156.             src += 2;
  2157.             abs_if_cnt++;       /*vb:   */
  2158.             if (isspace((unsigned char) *src)) {
  2159.                 while (isspace((unsigned char) *src)) {
  2160.                     src++;
  2161.                 }
  2162.                 /* Bedingung auswerten */
  2163.  
  2164.  
  2165.  
  2166.                 printf("****** WARNING ******* #if is not yet implemented\n");
  2167.  
  2168.  
  2169.                 string[0] = 0;  /*vb:   */
  2170.                 return (1);
  2171.             }
  2172.         }                       /* EO IF */
  2173.         /* ELIF */
  2174.         if (!strncmp(src, "elif", 4)) {
  2175.             src += 4;
  2176.             if (isspace((unsigned char) *src)) {
  2177.                 while (isspace((unsigned char) *src)) {
  2178.                     src++;
  2179.                 }
  2180.                 /* Bedingung auswerten */
  2181.  
  2182.  
  2183.  
  2184.  
  2185.  
  2186.                 printf("****** WARNING ******* #elif is not yet implemented\n");
  2187.  
  2188.  
  2189.  
  2190.  
  2191.                 string[0] = 0;  /*vb:   */
  2192.                 return (1);
  2193.             }
  2194.         }                       /* EO ELIF */
  2195.         /* ELSE */
  2196.         if (!strncmp(src, "else", 4)) {
  2197.             src += 4;
  2198.             if (isspace((unsigned char) *src) || *src == 0) {
  2199.                 while (isspace((unsigned char) *src)) {
  2200.                     src++;
  2201.                 }
  2202.  
  2203.                 if (!if_cnt) {
  2204.                     switch (ifstatus[incnesting]) {     /*vb:   */
  2205.                     case 0:
  2206.                         error(188);
  2207.                         return (0);
  2208.                         break;
  2209.                     case 1:
  2210.                         do_output = 0;
  2211.                         /* HIER: auf #endif suchen SearchENDIF(); */
  2212.                         /* HIER: ifnesting--; do_output=1; */
  2213.                         break;
  2214.                     case 2:
  2215.                         ifstatus[incnesting] = 3;       /*vb:   */
  2216.                         do_output = 1;
  2217.                         break;
  2218.                     case 3:
  2219.                         error(189);
  2220.                         return (0);
  2221.                         break;
  2222.                     }
  2223.                 }
  2224.                 string[0] = 0;  /*vb:    */
  2225.                 return (1);
  2226.             }
  2227.         }                       /* EO ELSE */
  2228.         /* ENDIF */
  2229.         if (!strncmp(src, "endif", 5)) {
  2230.             src += 5;
  2231.             abs_if_cnt--;       /*vb:   */
  2232.             if (isspace((unsigned char) *src) || *src == 0) {
  2233.                 while (isspace((unsigned char) *src)) {
  2234.                     src++;
  2235.                 }
  2236.                 /* HIER: Auf Zeilenende testen */
  2237.  
  2238.                 if (DEBUG & 32)
  2239.                     printf("-- #endif found, ");
  2240.  
  2241.                 if (if_cnt) {
  2242.                     if_cnt--;
  2243.                     if (DEBUG & 32)
  2244.                         printf("if_cnt decreased (to %d)\n", if_cnt);
  2245.                 } else {
  2246.                     if (DEBUG & 32)
  2247.                         printf("ifnesting: %d  ifstatus: %d\n", incnesting, ifstatus[incnesting]);
  2248.                     if (abs_if_cnt < 0 /*(incnesting==-1)||ifstatus[incnesting]==0 */ ) {       /*vb:   */
  2249.                         error(190);
  2250.                         return (0);
  2251.                     }
  2252.                     /*            ifnesting--; *//*vb:   */
  2253.                     /* HIER: evtl. do_output entsprechend ifstatus[] setzen */
  2254.                     /*vb: natuerlich    */
  2255.                     do_output = 1;
  2256.                     ifstatus[incnesting] = abs_if_cnt > 0;      /*vb: 1 oder 0   */
  2257.                 }
  2258.                 string[0] = 0;  /*vb: ja */
  2259.                 return (1);
  2260.             }
  2261.         }                       /* EO ENDIF */
  2262.         /*vb: andere Direktiven gegebenenfalls ueberspringen    */
  2263.         if (!do_output) {
  2264.             if (DEBUG & 32)
  2265.                 printf("do_output==0 => skipping: %s\n", src);
  2266.             string[0] = 0;
  2267.             return (1);
  2268.         }
  2269. /* DEFINE */
  2270.         if ( /*(do_output)&& */ (!strncmp(src, "define", 6))) {         /*vb:   */
  2271.             if (DEBUG & 32)
  2272.                 printf("#define found\n");
  2273.             src += 6;
  2274.             if (isspace((unsigned char) *src)) {
  2275.                 while (isspace((unsigned char) *src)) {
  2276.                     src++;
  2277.                 }
  2278.                 if (ParseIdentifier(src)) {
  2279.                     string[0] = 0;
  2280.                     return (1);
  2281.                 } else {
  2282.                     if (DEBUG & 32)
  2283.                         printf("ParseIdent returned 0\n");
  2284.                     return (0);
  2285.                 }
  2286.             }
  2287.         }                       /* EO DEFINE */
  2288.         /* UNDEF */
  2289.         if ( /*(do_output)&& */ (!strncmp(src, "undef", 5))) {  /*vb:   */
  2290.             src += 5;
  2291.             if (isspace((unsigned char) *src)) {
  2292.                 while (isspace((unsigned char) *src)) {
  2293.                     src++;
  2294.                 }
  2295.                 temp = src;
  2296.                 len = 0;
  2297.                 while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
  2298.                     temp++;
  2299.                     len++;
  2300.                 }
  2301.                 makro = FindMakroNode(mlist, src, len);
  2302.                 if (makro->flags & NODELETE) {
  2303.                     error(199);
  2304.                 } else {
  2305.                     DelMakroNode(&mlist, makro);
  2306.                 }
  2307.                 while (isspace((unsigned char) *temp)) {
  2308.                     temp++;
  2309.                 }
  2310.                 if (*temp != 0 && *temp != '\n') {
  2311.                     error(200);
  2312.                 }
  2313.                 string[0] = 0;
  2314.                 return (1);
  2315.             }
  2316.         }                       /* EO UNDEF */
  2317.         /* INCLUDE */
  2318.         if ( /*(do_output)&& */ (!strncmp(src, "include", 7))) {        /*vb:   */
  2319.             src += 7;
  2320.             if (isspace((unsigned char) *src)) {
  2321.                 while (isspace((unsigned char) *src)) {
  2322.                     src++;
  2323.                 }
  2324.                 if (*src != '<' && *src != '\"') {
  2325.                     /* Versuchen den Rest zu expandieren */
  2326.                     inclinelist = Str2List(src);
  2327.                     if (!ExpandList(&inclinelist)) {
  2328.                         if (List2Str(inclinelist, src, MAXINPUT - (src - string))) {
  2329.                             /* HIER exit ? */
  2330.                         }
  2331.                     } else {
  2332.                         error(191);     /* HIER exit ? */
  2333.                     }
  2334.                 }
  2335. /*vb: geaendert, so dass #include "..." auch noch im Standardpfad sucht */
  2336.                 if (DEBUG & 32)
  2337.                     printf("includename=%s\n", src);
  2338.                 if (*src == '<' || *src == '\"') {
  2339.                     char *m = src, c;
  2340.                     if (*src == '<')
  2341.                         c = '>';
  2342.                     else
  2343.                         c = '\"';
  2344.                     if (*src == '\"') {
  2345.                         /* im aktuellen Verzeichnis suchen und includen */
  2346.                         src++;
  2347.                         temp = src;
  2348.                         len = 0;
  2349.                         while (*temp != '\"') {
  2350.                             temp++;
  2351.                             len++;
  2352.                         }
  2353.                         temp++;
  2354.                         while (isspace((unsigned char) *temp))
  2355.                             temp++;
  2356.                         if (*temp) {
  2357.                             error(200);
  2358.                         }
  2359.                         temp = (char *) malloc(len + 1);
  2360.                         if (temp) {
  2361.                             strncpy(temp, src, len);
  2362.                             *(temp + len) = 0;
  2363.                             if (pp_include(temp)) {
  2364.                                 AddStrNode(&strlist, NULL, temp);
  2365.                                 string[0] = 0;
  2366.                                 return (1);
  2367.                             } else {
  2368.                                 if (temp)
  2369.                                     free(temp);
  2370. /*vb:
  2371.    error("pp: cannot open file to include",0);
  2372.    return(0); */
  2373.                             }
  2374.                         } else {
  2375.                             error(196);
  2376.                         }       /* HIER: Exit? */
  2377.                     }
  2378.                     /* in den Standard-Verzeichnissen suchen und includen */
  2379.                     src = m;
  2380.                     src++;
  2381.                     temp = src;
  2382.                     len = 0;
  2383.                     while (*temp != c && *temp != 0) {
  2384.                         temp++;
  2385.                         len++;
  2386.                     }           /*vb: sicherer */
  2387.                     temp++;
  2388.                     while (isspace((unsigned char) *temp))
  2389.                         temp++;
  2390.                     if (*temp) {
  2391.                         error(200);
  2392.                     }
  2393.                     temp = NULL;
  2394.                     for (i = 0; i < incpathc; i++) {
  2395.                         complete_len = strlen(incpath[i]) + len;
  2396.                         temp = (char *) malloc(complete_len + 1);
  2397.                         if (temp) {
  2398.                             strcpy(temp, incpath[i]);
  2399.                             strncat(temp, src, len);
  2400.                             *(temp + complete_len) = 0;
  2401.                             if (pp_include(temp)) {
  2402.                                 AddStrNode(&strlist, NULL, temp);
  2403.                                 if (DEBUG & 32)
  2404.                                     printf("include <%s> found\n", temp);
  2405.                                 string[0] = 0;
  2406.                                 return (1);
  2407.                             } else {
  2408.                                 if (temp)
  2409.                                     free(temp);
  2410.                             }
  2411.                         } else {
  2412.                             error(196);
  2413.                         }       /* HIER: Exit ? */
  2414.                     }           /* of FOR i */
  2415.                     error(191);
  2416.                     return (0);
  2417.                 } else {
  2418.                     error(192);
  2419.                     return (0);
  2420.                 }
  2421.             } else {
  2422.                 error(193);
  2423.                 return (0);
  2424.             }
  2425.         }                       /* EO INCLUDE */
  2426.         /* LINE */
  2427.         if (!strncmp(src, "line", 4)) {
  2428.             src += 4;
  2429.             if (isspace((unsigned char) *src)) {
  2430.                 return (1);     /* Ignorieren und an Compiler weiterreichen */
  2431.             }
  2432.         }                       /* EO LINE */
  2433.         /* ERROR */
  2434.         if (!strncmp(src, "error", 5)) {
  2435.             src += 5;
  2436.             if (isspace((unsigned char) *src)) {
  2437.                 while (isspace((unsigned char) *src)) {
  2438.                     src++;
  2439.                 }
  2440.  
  2441.                 return (1);
  2442.             }
  2443.         }                       /* EO ERROR */
  2444.         /* PRAGMA */
  2445.         if (!strncmp(src, "pragma", 6)) {
  2446.             src += 6;
  2447.             if (isspace((unsigned char) *src)) {
  2448.                 while (isspace((unsigned char) *src)) {
  2449.                     src++;
  2450.                 }
  2451.  
  2452.                 return (1);
  2453.             }
  2454.         }                       /* EO PRAGMA */
  2455.         /* Unknown */
  2456.         /*    if(do_output){ */
  2457.         /*vb:   */
  2458.         error(193);
  2459.         return (0);
  2460.         /*    } *//*vb:   */
  2461.     } else if (do_output) {
  2462.         /* Normale Anweisung. Komplette Zeile expandieren */
  2463.  
  2464. /*vb:   */
  2465.  
  2466.         linelist = Str2List(string);
  2467.  
  2468.         if (DEBUG & 32)
  2469.             PrintTL(linelist);
  2470.  
  2471. /*vb: */
  2472.         did_expand = 0;
  2473.  
  2474.         if (result = ExpandList(&linelist)) {
  2475.             switch (result) {
  2476.             case OUT_OF_MEM:
  2477.                 error(196);
  2478.                 break;
  2479.             case NUM_OF_ARGS:
  2480.                 error(194);
  2481.                 break;
  2482.             case ARG_EXPECTED:
  2483.                 error(195);
  2484.                 break;
  2485.             default:
  2486.                 ierror(0);
  2487.                 break;
  2488.             }
  2489.             DelStrList(&linelist);
  2490.             return (0);
  2491.         }
  2492.         if (DEBUG & 32)
  2493.             PrintTL(linelist);
  2494.  
  2495. /*vb: List2Str nur aufrufen, falls etwas expandiert wurde   */
  2496.         if (did_expand && !List2Str(linelist, string, MAXINPUT)) {
  2497.             DelStrList(&linelist);
  2498.             return (0);
  2499.         }
  2500.         DelStrList(&linelist);
  2501.  
  2502. /*vb:   */
  2503.     } else
  2504.         string[0] = 0;
  2505.     return (1);
  2506. }
  2507.